//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __MISC_H___
#define __MISC_H___

struct mtx{
    void *pM;
};

typedef int64_t TIME;

typedef struct timeval {
    long    tv_sec;     /* seconds */
    long    tv_usec;    /* and microseconds */
}TIMEVAL;

typedef struct Signal{
    void * event;
}Signal;

struct cv {
    void * pCon;
};


#define __DECL_HARDWARE_SAVED_REGS      \
    uint32_t    eip;                    \
    uint32_t    cs;                     \
    uint32_t    eflags;                 \
    uint32_t    _esp;                   \
    uint32_t    _ss;

#define __DECL_SOFTWARE_SAVED_REGS      \
    uint32_t    ebx;                    \
    uint32_t    ecx;                    \
    uint32_t    edx;                    \
    uint32_t    esi;                    \
    uint32_t    edi;                    \
    uint32_t    ebp;                    \
    uint32_t    eax;                    \
    uint32_t    ds;                     \
    uint32_t    es;

typedef uint32_t                errorcode_t;
typedef void          *PTR;

#ifndef MISC
typedef uint8_t irq_t;
typedef uint32_t irqs_t;

typedef enum ipl_t {
    IPL0        = 0,
    IPL1        = 1,
    IPL2        = 2,
    IPL3        = 3,
    IPL4        = 4,
    IPL5        = 5,
    IPL6        = 6,
    IPL7        = 7,
    IPL8        = 8,
    IPL9        = 9,
    IPL10       = 10,
    IPL11       = 11,
    IPL12       = 12,
    IPL13       = 13,
    IPL14       = 14,
    IPL15       = 15,
    IPL16       = 16,
    IPL17       = 17,
    IPL18       = 18,
    IPL19       = 19,
    IPL20       = 20,
    IPL21       = 21,
    IPL22       = 22,
    IPL23       = 23,
    IPL24       = 24,
    IPL25       = 25,
    IPL26       = 26,
    IPL27       = 27,
    IPL28       = 28,
    IPL29       = 29,
    IPL30       = 30,
    IPL31       = 31,
    IPL_Base    = 32
} ipl_t;

#define MAX_IPL     IPL0
#define MIN_IPL     IPL31

typedef struct InterruptContext {
    __DECL_SOFTWARE_SAVED_REGS
    union {
        irq_t       irq;
        errorcode_t errorcode;
        uint32_t    uSystemCallNo;
    } u;
    __DECL_HARDWARE_SAVED_REGS
} InterruptContext;
#endif

#define m_MALLOC(space, cast, size, type, flags) \
(space) = (cast)m_DevMalloc((UInt32)(size), type, flags); \
if (space != NULL) memset(space,0,(UInt32)size)

typedef void (CDECL *isr_t)(irq_t, void *, InterruptContext *);



EXTERN_C int  __cdecl PhysAddr(char *va);
EXTERN_C void __cdecl bzero(void *buf, size_t size);
EXTERN_C void __cdecl AddDevice(irq_t irq, ipl_t ipl, isr_t isr, void *pvDevice);
EXTERN_C void __cdecl Signal_init(struct Signal *pEvent);
EXTERN_C void __cdecl PulseByISR(struct Signal *pEvent, int i);
EXTERN_C void __cdecl Pulse(struct Signal *pEvent, int i);
EXTERN_C void __cdecl Wait(struct Signal *pEvent, int *i);
EXTERN_C void __cdecl getmicrotime(struct timeval* time);
EXTERN_C void __cdecl Mtx_destroy(struct mtx* pMtx);
EXTERN_C void __cdecl Mtx_init(struct mtx *pMtx);
EXTERN_C void __cdecl Mtx_unlock(struct mtx *pMtx);
EXTERN_C void __cdecl Mtx_lock(struct mtx *pMtx);
EXTERN_C int  NetLock();
EXTERN_C void NetUnlock();
EXTERN_C void __cdecl Cv_init(struct cv *pCv);
EXTERN_C int  __cdecl Cv_timedwait(struct cv *pCv, struct mtx* pMtx, TIME tout);
EXTERN_C void __cdecl Cv_signal(struct cv *pCv);
EXTERN_C void __cdecl Cv_destroy(struct cv *pCv);

EXTERN_C void * __cdecl Malloc(size_t n);
EXTERN_C PTR __cdecl FSMALLOC(UInt32 NBytes, UInt32 Tag, UInt32 Options);
EXTERN_C PTR __cdecl DevMalloc(UInt32 NBytes, UInt32 Tag, UInt32 Options);
EXTERN_C PTR __cdecl m_DevMalloc(UInt32 NBytes, UInt32 Tag, UInt32 Options);
EXTERN_C void __cdecl FSFREE(PTR Ptr, UInt32 Tag);
EXTERN_C PTR __cdecl KernelAlloc(uint_t uOrder);
EXTERN_C unsigned int __cdecl mRoundUp2Order(unsigned int u);

//EXTERN_C ECode __cdecl ThdEntry(void* pArg);
EXTERN_C void __cdecl CreateThread(void *pArg);


#define cv_init(a, b)           Cv_init(a)
#define cv_timedwait(a, b, c)   Cv_timedwait(a, b, c)
#define cv_signal(a)            Cv_signal(a)
#define cv_destroy(a)           Cv_destroy(a)


#define mtx_init(a, b, c, d)    Mtx_init(a)
#define mtx_destroy(a)          Mtx_destroy(a)
#define mtx_lock(a)             Mtx_lock(a)
#define mtx_unlock(a)           Mtx_unlock(a)

#define splbio() NetLock()
#define splx(x)  NetUnlock()
#define splimp() NetLock()
#define splnet() NetLock()
#define spltty() NetLock()

#endif//__MISC_H___
